﻿using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Xml;
using TicketMLib;

namespace AreaStructManipulators
{
    public class AreaStructMan
    {
        #region Area Structure Manipulation
        /// <summary>
        /// This method reads the areas structure for a selected project
        /// </summary>
        /// <param name="sProject">Session variable that represents selected project</param>
        /// <returns></returns>              
        public XmlDocument GetAreasStructure(string sProject)
        {
            #region Get Variable Values from existing config file
            string uName;
            string passwd;
            string domain;
            string tfs;
            string collection;
            string _project;
            Utils.SetGenVarValues(sProject, out uName, out passwd, out domain, out tfs, out collection, out _project);
            #endregion

            try
            {
                TfsTeamProjectCollection tpc = Utils.Connect2Tfs(uName, passwd, domain, tfs, collection);
                ICommonStructureService StructureService = (ICommonStructureService)tpc.GetService(typeof(ICommonStructureService));
                //Gets Area/Iteration base Project

                ProjectInfo projectInfo = StructureService.GetProjectFromName(_project);
                NodeInfo[] nodes = StructureService.ListStructures(projectInfo.Uri);
                XmlDocument doc1 = new XmlDocument();
                doc1.LoadXml(StructureService.GetNodesXml(new string[] { nodes[0].Uri }, true).InnerXml);
                XmlNodeList allNodes = doc1.FirstChild.SelectNodes("//*");
                return ProcessNode(allNodes, sProject);
            }
            catch
            {
                throw;
            }

        }
        /// <summary>
        /// This is a helper method that converts the passed nodes (areas) into a flat XmlDocument object
        /// </summary>
        /// <param name="allNodes">All area structure nodes for the selected project</param>
        /// <param name="sProject">Session variable representing selected project</param>
        /// <returns></returns>
        private XmlDocument ProcessNode(XmlNodeList allNodes, string sProject)
        {
            XmlDocument doc = new XmlDocument();
            XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", null, null);
            doc.AppendChild(dec);
            XmlElement root1 = doc.CreateElement("Project");
            XmlAttribute nameAttr = doc.CreateAttribute("Name");
            nameAttr.Value = sProject;
            root1.Attributes.Append(nameAttr);
            doc.AppendChild(root1);
            try
            {
                for (int i = 1; i < allNodes.Count; i++)
                {

                    if (allNodes[i].Name != "Children")
                    {
                        XmlNode elem = doc.CreateNode(XmlNodeType.Element, "SubArea", null);
                        XmlAttribute attrib = doc.CreateAttribute("Name");
                        //Structure service contains format that is not compatible further. So we need to process it first.
                        attrib.Value = allNodes[i].Attributes["Path"].Value.Split(new char[] { '\\' }, 4).GetValue(3).ToString();
                        elem.Attributes.Append(attrib);
                        root1.AppendChild(elem);
                    }
                }
            }
            catch
            {

                throw;
            }
            return doc;
        }
        public int GetAreaId(string AreaPath, string sProject)
        {
            try
            {
                #region Get Variable Values from existing config file
                string uName;
                string passwd;
                string domain;
                string tfs;
                string collection;
                string _project;
                Utils.SetGenVarValues(sProject, out uName, out passwd, out domain, out tfs, out collection, out _project);
                #endregion

                TfsTeamProjectCollection tpc = Utils.Connect2Tfs(uName, passwd, domain, tfs, collection);
                var wiStore = tpc.GetService<WorkItemStore>();
                var project = wiStore.Projects[_project];
                NodeCollection nodes = project.AreaRootNodes;

                Node area = project.FindNodeInSubTree(AreaPath, Node.TreeType.Area);
                return area.Id;

            }
            catch
            {

                throw;
            }

        }
        /// <summary>
        /// This method synchornizes the escalation structure after changes are made
        /// </summary>
        /// <param name="doc">This represents the current area structure of the selected project</param>
        /// <param name="sProject">Session variable that represents the selected project</param>
        public void SyncEscalationStructure(XmlDocument doc, string sProject, string EscalationConfigPath)
        {
            try
            {
                XmlDocument EscalationArea = new XmlDocument();
                EscalationArea.Load(HttpContext.Current.Server.MapPath(EscalationConfigPath)); //Existing escalation accounts
                //Read existing nodes in the Areas of the project (passed as parameter by calling method)
                XmlNodeList AllAreas = doc.DocumentElement.SelectNodes("//SubArea");
                foreach (XmlNode area in AllAreas)
                {
                    //check if a node in AreaNoDaysEmails.xml config file exists for that area
                    if (EscalationArea.SelectSingleNode("/Area_Email_Days/Area[@Project='" + sProject + "' and @Name='" + area.Attributes["Name"].Value + "']") == null) //if project node is present but a specific area does not exist
                    {
                        //if that node does not exist, create one
                        XmlNode root = EscalationArea.DocumentElement;
                        XmlNode NewArea = EscalationArea.CreateNode(XmlNodeType.Element, "Area", null);
                        XmlAttribute NewAreaName = EscalationArea.CreateAttribute("Name");
                        XmlAttribute NewEmail = EscalationArea.CreateAttribute("Email");
                        XmlAttribute NewDays = EscalationArea.CreateAttribute("Days");
                        XmlAttribute NewProject = EscalationArea.CreateAttribute("Project");
                        //set standard values to attributes and area name as of selected area
                        NewEmail.Value = "";
                        NewDays.Value = "2";
                        NewAreaName.Value = area.Attributes["Name"].Value;
                        NewProject.Value = sProject;

                        NewArea.Attributes.Append(NewAreaName);
                        NewArea.Attributes.Append(NewDays);
                        NewArea.Attributes.Append(NewEmail);
                        NewArea.Attributes.Append(NewProject);
                        //append the node to the structure and save the file
                        root.AppendChild(NewArea);
                        EscalationArea.Save(HttpContext.Current.Server.MapPath(EscalationConfigPath));
                    }
                }
            }
            catch
            {

                throw;
            }
        }

        #endregion
    }
}
